﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WebSysCore
{
    public class DataBase
    {
        static IS2_DBDataContext d = new IS2_DBDataContext();
        /// <summary>
        /// Return list of all user.
        /// </summary>
        /// <returns></returns>
        public static List<User> GetAllUser()
        {
            return d.Users.ToList();
        }


        /// <summary>
        /// Đưa ra thông tin môn học dựa vào Id của nó
        /// </summary>
        /// <param name="subjectId"></param>
        /// <returns></returns>
        public static Subject GetSubjectByID(int subjectId)
        {
            Subject s = null;
            var query = from q in d.Subjects
                        where q.SubjectID == subjectId
                        select q;
            if (query.Count() > 0)
            {
                s = query.ToList()[0];
            }
            return s;
        }



        /// <summary>
        /// Lấy danh sách các môn học của một thời khóa biểu
        /// </summary>
        /// <param name="scheduleInListId"></param>
        /// <returns></returns>
        public static List<Subject> GetAllSubjectOfSchedule(int scheduleInListId)
        {
            var query = from q in d.Subjects
                        where q.ScheduleInListId == scheduleInListId
                        select q;
            return query.ToList();
        }


        /// <summary>
        /// Lấy danh sách các giáo viên dạy của một môn.
        /// </summary>
        /// <param name="subjectId"></param>
        /// <returns></returns>
        public static List<Teacher> GetTeacherOfSubject(int subjectId)
        {
            var query = from t in d.Teachers
                        join o in d.TeacherDetails
                        on t.TeacherID equals o.TeacherID
                        where o.SubjectID == subjectId
                        select t;
            return query.ToList();

        }

        /// <summary>
        /// Lấy danh sách tất cả các khách hàng.
        /// </summary>
        /// <returns></returns>
        public static List<Customer> GetAllCustomer()
        {
            var query = from q in d.Customers
                        where q.Deleted == 0
                        select q;
            return query.ToList();
        }


        /// <summary>
        /// Insert a schedule to list and return ID;
        /// </summary>
        /// <param name="sch"></param>
        /// <returns></returns>
        public static int AddSchedule(ListSchedule sch)
        {
            d.ListSchedules.InsertOnSubmit(sch);
            d.SubmitChanges();
            int t = d.ListSchedules.Max(o => o.ScheduleIdInList);
            return t;
        }


        /// <summary>
        /// Thêm vào cơ sở dữ liệu danh sách các ngày học trả về số ngày được thêm
        /// </summary>
        /// <param name="lstDay"></param>
        /// <returns></returns>
        public static int InsertDays(List<Day> lstDay)
        {
            d.Days.InsertAllOnSubmit(lstDay);
            d.SubmitChanges();
            return lstDay.Count;
        }


        /// <summary>
        /// Thêm vào cơ sở dữ liệu danh sách các buổi học trả về số buổi học đc thêm
        /// </summary>
        /// <param name="lstSes"></param>
        public static void InsertSession(List<Session> lstSes)
        {
            d.Sessions.InsertAllOnSubmit(lstSes);
            d.SubmitChanges();
        }

        /// <summary>
        /// Thêm vào cơ sở dữ liệu danh sách các tiết học trả về số tiết học đc thêm 
        /// </summary>
        /// <param name="lstLes"></param>
        public static void InsertLession(List<Lession> lstLes)
        {
            d.Lessions.InsertAllOnSubmit(lstLes);
            d.SubmitChanges();
        }


        /// <summary>
        /// Thêm vào cơ sở dữ liệu danh sách các môn học
        /// </summary>
        /// <param name="lstSelectSub"></param>
        public static void InsertSubject(List<Subject> lstSelectSub)
        {
            d.Subjects.InsertAllOnSubmit(lstSelectSub);
            d.SubmitChanges();
        }


        /// <summary>
        /// Lấy danh sách tất cả các môn học trong một thời khóa biểu
        /// </summary>
        /// <param name="scheduleInListId"></param>
        /// <returns></returns>
        public static List<Subject> GetAllSubject(int scheduleInListId)
        {
            //throw new NotImplementedException();
            var query = from q in d.Subjects
                        where q.ScheduleInListId == scheduleInListId
                        select q;
            return query.ToList();
        }


        /// <summary>
        /// Lấy danh sách tất cả các ngày học trong một thời khóa biểu
        /// </summary>
        /// <param name="scheduleInListId"></param>
        /// <returns></returns>
        public static List<Day> GetAllDay(int scheduleInListId)
        {
            //throw new NotImplementedException();
            var query = from q in d.Days
                        where q.ScheduleInListId == scheduleInListId
                        select q;
            return query.ToList();
        }


        /// <summary>
        /// Lấy danh sách tất cả các buổi học trong một thời khóa biểu
        /// </summary>
        /// <param name="scheduleInListId"></param>
        /// <returns></returns>
        public static List<Lession> GetAllLession(int scheduleInListId)
        {
            //throw new NotImplementedException();
            var query = from q in d.Lessions
                        where q.ScheduleInListId == scheduleInListId
                        select q;
            return query.ToList();
        }

        /// <summary>
        /// Thêm giàng buộc môn học tránh tiết
        /// </summary>
        /// <param name="notAtLst"></param>
        public static void InsertSubjectNotAt(List<SubjectNotAt> notAtLst)
        {
            //throw new NotImplementedException();

            if (notAtLst.Count > 1)
            {

                var query = from q in d.SubjectNotAts
                            where q.ScheduleInListId == notAtLst[0].ScheduleInListId && q.SubjectID == notAtLst[0].SubjectID
                                    && q.DayID == notAtLst[0].DayID && q.SessionID == notAtLst[0].SessionID
                            select q;
                d.SubjectNotAts.DeleteAllOnSubmit(query);
                d.SubmitChanges();
            }
            d.SubjectNotAts.InsertAllOnSubmit(notAtLst);
            d.SubmitChanges();
        }


        /// <summary>
        /// Lấy thông tin giàng buộc môn học tránh tiết trong một thời khóa biểu xác định của một môn học xác định
        /// scheduleInListId: mã của thời khóa biểu cần lấy.
        /// p: Mã của môn học cần lấy
        /// </summary>
        /// <param name="scheduleInListId"></param>
        /// <param name="p"></param>
        /// <returns></returns>
        public static List<SubjectNotAt> GetSubjectNotAt(int scheduleInListId, int p)
        {
            //throw new NotImplementedException();
            var query = from q in d.SubjectNotAts
                        where q.ScheduleInListId == scheduleInListId && q.SubjectID == p
                        select q;
            return query.ToList();
        }


        /// <summary>
        /// Lấy danh sách tất cả giáo viên của thời khóa biểu xác định
        /// </summary>
        /// <param name="scheduleInListId"></param>
        /// <returns></returns>
        public static List<Teacher> GetAllTeacher(int scheduleInListId)
        {
            //throw new NotImplementedException();
            var quer = from q in d.Teachers
                       where q.ScheduleInListId == scheduleInListId
                       select q;
            return quer.ToList();
        }



        /// <summary>
        /// Thêm một giáo viên và thông tin các môn mà giáo viên đó dạy
        /// </summary>
        /// <param name="t"></param>
        /// <param name="lstDe"></param>
        public static void InsertTeacher(Teacher t, List<TeacherDetail> lstDe)
        {
            //throw new NotImplementedException();
            Teacher t1 = t;
            t1.TeacherDetails.AddRange(lstDe);
            d.Teachers.InsertOnSubmit(t1);
            d.SubmitChanges();
        }


        /// <summary>
        /// Xóa một giáo viên khỏi CSDL
        /// </summary>
        /// <param name="t"></param>
        public static void DeleteTeacher(Teacher t)
        {
            //throw new NotImplementedException();
            var query = from q in d.TeacherDetails
                        where q.TeacherID == t.TeacherID
                        select q;
            d.TeacherDetails.DeleteAllOnSubmit(query);
            d.SubmitChanges();
            var query2 = from q in d.Teachers
                         where q.TeacherID == t.TeacherID
                         select q;
            d.Teachers.DeleteAllOnSubmit(query2);
            d.SubmitChanges();
        }

        public static void DeleteTeacher(List<int> lstId)
        {
            //List<TeacherDetail> lstTD = new List<TeacherDetail>();
            foreach (int t in lstId)
            {
                var query = from q in d.TeacherDetails
                            where q.TeacherID == t
                            select q;
                //lstTD.AddRange(query);
                d.TeacherDetails.DeleteAllOnSubmit(query);
                d.SubmitChanges();
                var query2 = from q in d.Teachers
                             where q.TeacherID == t
                             select q;
                d.Teachers.DeleteAllOnSubmit(query2);
                d.SubmitChanges();
            }
        }

        /// <summary>
        /// Lấy danh sách các môn học của một giáo viên
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public static List<Subject> GetSubjectOfTeacher(Teacher t)
        {
            //throw new NotImplementedException();
            var query = from q in d.Subjects
                        join o in d.TeacherDetails
                        on q.SubjectID equals o.SubjectID
                        where o.TeacherID == t.TeacherID
                        select q;
            return query.ToList();
        }


        /// <summary>
        /// Lấy thông tin của một giáo viên theo Id
        /// </summary>
        /// <param name="idToUpdate"></param>
        /// <returns></returns>
        public static Teacher GetTeacherById(int idToUpdate)
        {
            //throw new NotImplementedException();
            var query = from q in d.Teachers
                        where q.TeacherID == idToUpdate
                        select q;
            if (query.Count() > 0)
            {
                return query.ToList()[0];
            }
            else
            {
                return null;
            }
        }


        /// <summary>
        /// Update thông tin giáo viên
        /// </summary>
        /// <param name="t"></param>
        /// <param name="lstDe"></param>
        public static void UpdateTeacher(Teacher t, List<TeacherDetail> lstDe)
        {
            //throw new NotImplementedException();
            try
            {
                List<TeacherDetail> all = d.TeacherDetails.ToList();
                d.TeacherDetails.DeleteAllOnSubmit(from dt in all
                                                   where dt.TeacherID == t.TeacherID
                                                   select dt);
                d.SubmitChanges();
                Teacher t1 = d.Teachers.First(q => q.TeacherID == t.TeacherID);
                t1.FullName = t.FullName;
                t1.MinLession = t.MinLession;
                t1.Comment = t.Comment;
                t1.TeacherDetails.AddRange(lstDe);
                d.SubmitChanges();
                //return true;
            }
            catch
            {
                //return false;
            }

        }

        public static void UpdateTeacher(int teacherId, Teacher t, List<TeacherDetail> details)
        {
            var query = from q in d.Teachers
                        where q.TeacherID == teacherId
                        select q;
            if (query.Count() > 0)
            {
                Teacher t1 = query.ToList()[0];
                t1.FullName = t.FullName;
                t1.MinLession = t.MinLession;
                t1.Comment = t.Comment;
                t1.TeacherDetails.Clear();
                t1.TeacherDetails.AddRange(details);
                d.SubmitChanges();
            }
        }

        /// <summary>
        /// Kiểm tra xem tất cả các môn đều có giáo viên dạy hay chưa
        /// </summary>
        /// <param name="scheduleInListId"></param>
        /// <returns></returns>
        public static bool AllSubjectHasTeacher(int scheduleInListId)
        {
            //throw new NotImplementedException();
            bool ok = true;
            List<Subject> lstSub = (from s in d.Subjects
                                    where s.NotNeedTeacher < 1 && s.ScheduleInListId == scheduleInListId
                                    select s).ToList();
            List<TeacherDetail> all = (from t in d.TeacherDetails
                                       join t1 in d.Teachers
                                       on t.TeacherID equals t1.TeacherID
                                       where t1.ScheduleInListId == scheduleInListId
                                       select t).ToList();
            foreach (Subject s in lstSub)
            {
                List<TeacherDetail> lst = (from dt in all
                                           where dt.SubjectID == s.SubjectID
                                           select dt).ToList();
                if (lst.Count == 0)
                {
                    ok = false;
                    break;
                }
            }
            return ok;

        }


        /// <summary>
        /// Lấy danh sách các buổi học của một thời khóa biểu
        /// </summary>
        /// <param name="scheduleInListId"></param>
        /// <returns></returns>
        public static List<Session> GetAllSession(int scheduleInListId)
        {
            //throw new NotImplementedException();
            var query = from q in d.Sessions
                        where q.ScheduleInListId == scheduleInListId
                        select q;
            return query.ToList();
        }


        /// <summary>
        /// Lấy thông tin các buổi nghỉ dạy của giáo viên
        /// </summary>
        /// <param name="teacher"></param>
        /// <returns></returns>
        public static List<FixTeacherSession> GetFixOfTeacher(Teacher teacher)
        {
            //throw new NotImplementedException();
            var query = from q in d.FixTeacherSessions
                        where q.TeacherID == teacher.TeacherID
                        select q;
            return query.ToList();
        }

        public static List<FixTeacherSession> GetFixOfTeacher(int teacherId, int dayId)
        {
            var query = from q in d.FixTeacherSessions
                        where q.TeacherID == teacherId && q.DayID == dayId
                        select q;
            return query.ToList();
        }


        /// <summary>
        /// Lấy danh sách các buổi nghỉ dạy của một giáo viên trong một ngày của một thời khóa biểu
        /// scheduleInListId: Mã thời khóa biểu cần lấy
        /// p: Mã giáo viên cần lấy
        /// p_3: Mã ngày học cần lấy
        /// </summary>
        /// <param name="scheduleInListId"></param>
        /// <param name="p"></param>
        /// <param name="p_3"></param>
        /// <returns></returns>
        public static List<Session> GetFixTeacherSessionOfTeacher(int scheduleInListId, int p, int p_3)
        {
            //throw new NotImplementedException();
            var query = from q in d.Sessions
                        join o in d.FixTeacherSessions
                        on q.SessionID equals o.SessionID
                        where q.ScheduleInListId == scheduleInListId && o.TeacherID == p && o.DayID == p_3
                        select q;
            return query.ToList();
        }


        /// <summary>
        /// Xóa khỏi CSDL thông tin nghỉ dạy của một giáo viên vào một ngày xác định trong một thời khóa biểu
        /// scheduleInListId: Mã thời khóa biểu
        /// p: Mã giáo viên
        /// p_3: Mã ngày
        /// </summary>
        /// <param name="scheduleInListId"></param>
        /// <param name="p"></param>
        /// <param name="p_3"></param>
        public static void DelFixTeacherSession(int scheduleInListId, int p, int p_3)
        {
            //throw new NotImplementedException();
            var query = from q in d.FixTeacherSessions
                        where q.ScheduleInListId == scheduleInListId && q.TeacherID == p && q.DayID == p_3
                        select q;
            d.FixTeacherSessions.DeleteAllOnSubmit(query);
            d.SubmitChanges();
        }


        /// <summary>
        /// Thêm danh sách các thông tin nghỉ dạy của giáo viên vào CSDL
        /// </summary>
        /// <param name="lstNFix"></param>
        public static void InsertFixTeacherSession(List<FixTeacherSession> lstNFix)
        {
            d.FixTeacherSessions.InsertAllOnSubmit(lstNFix);
            d.SubmitChanges();
        }
        public static Day GetDayById(int id)
        {
            var query = from q in d.Days
                        where q.DayID == id
                        select q;
            if (query.Count() > 0)
            {
                return query.ToList()[0];
            }
            else
            {
                return null;
            }
        }
        public static Session GetSessionById(int id)
        {
            var query = from q in d.Sessions
                        where q.SessionID == id
                        select q;
            if (query.Count() > 0)
            {
                return query.ToList()[0];
            }
            else
            {
                return null;
            }

        }
        public static List<TeacherFixInfo> GetTeacherFix(int scheduleInListId)
        {
            var query = from q in d.Teachers
                        join q1 in d.FixTeacherSessions
                        on q.TeacherID equals q1.TeacherID
                        where q.ScheduleInListId == scheduleInListId
                        select q;
            query = query.Distinct();
            List<Teacher> lstTeacher = query.ToList();
            List<TeacherFixInfo> lstTFI = new List<TeacherFixInfo>();
            foreach (Teacher t in lstTeacher)
            {
                TeacherFixInfo tfi = new TeacherFixInfo();
                tfi.teach = t;
                tfi.lstDay = new List<Day>();
                tfi.lstLstSession = new List<List<Session>>();
                List<FixTeacherSession> lstFTS = GetFixOfTeacher(t);
                foreach (FixTeacherSession fts in lstFTS)
                {
                    Day dd = GetDayById(fts.DayID);
                    var query2 = from q in tfi.lstDay
                                 where q.DayID == fts.DayID
                                 select q;
                    if (query2.Count() == 0)
                    {
                        tfi.lstDay.Add(dd);
                    }
                }
                foreach (Day dd in tfi.lstDay)
                {
                    List<Session> lstS = GetFixTeacherSessionOfTeacher(scheduleInListId, t.TeacherID, dd.DayID);
                    tfi.lstLstSession.Add(lstS);
                }
                lstTFI.Add(tfi);
            }
            return lstTFI;
        }

        /// <summary>
        /// Lấy danh sách các chương trình đào tạo
        /// </summary>
        /// <param name="scheduleInListId"></param>
        /// <returns></returns>
        public static List<Program> GetAllProgram(int scheduleInListId)
        {
            //throw new NotImplementedException();
            var query = from q in d.Programs
                        where q.ScheduleInListId == scheduleInListId
                        select q;
            return query.ToList();
        }


        /// <summary>
        /// Lấy thông tin chi tiết của một chương trình đào tạo
        /// </summary>
        /// <param name="currentProgram"></param>
        /// <returns></returns>
        public static List<ProgramDetail> GetDetailOfProgram(Program currentProgram)
        {
            //throw new NotImplementedException();
            var query = from q in d.ProgramDetails
                        where q.ProgramID == currentProgram.ProgramID
                        select q;
            return query.ToList();
        }

        public static List<ProgramFull> GetProgramInfo(int scheduleInListId)
        {
            List<ProgramFull> lstPF = new List<ProgramFull>();
            var query = from q in d.Programs
                        where q.ScheduleInListId == scheduleInListId
                        select q;
            List<Program> lstP = query.ToList();
            foreach (Program p in lstP)
            {
                ProgramFull pf = new ProgramFull();
                pf.pro = p;
                pf.lstSubject = new List<Subject>();
                pf.lstNumLession = new List<int>();
                pf.lstComment = new List<string>();
                List<ProgramDetail> lstPDT = (from q in d.ProgramDetails
                                              where q.ProgramID == p.ProgramID
                                              select q).ToList();
                foreach (ProgramDetail pd in lstPDT)
                {
                    pf.lstSubject.Add(d.Subjects.Single(o => o.SubjectID == pd.SubjectID));
                    pf.lstNumLession.Add(pd.NumLession);
                    pf.lstComment.Add(pd.Comment);
                }
                lstPF.Add(pf);
            }
            return lstPF;
        }

        /// <summary>
        /// Thêm vào CSDL một chương trình đào tạo vào chi tiết của nó
        /// </summary>
        /// <param name="newProgram"></param>
        /// <param name="lstDT"></param>
        public static void InsertProgramAndDetail(Program newProgram, List<ProgramDetail> lstDT)
        {
            //throw new NotImplementedException();
            newProgram.ProgramDetails.AddRange(lstDT);
            d.Programs.InsertOnSubmit(newProgram);
            d.SubmitChanges();
        }



        /// <summary>
        /// Cập nhật một chương trình đào tạo và chi tiết.
        /// </summary>
        /// <param name="currentProgram"></param>
        /// <param name="newProgram"></param>
        /// <param name="lstNewDT"></param>
        public static void UpdateProgram(Program currentProgram, Program newProgram, List<ProgramDetail> lstNewDT)
        {
            //throw new NotImplementedException();
            var query = d.Programs.Single(o => o.ProgramID == currentProgram.ProgramID);
            var query2 = from de in d.ProgramDetails
                         where de.ProgramID == query.ProgramID
                         select de;
            d.ProgramDetails.DeleteAllOnSubmit(query2);
            d.SubmitChanges();
            query.ProgramName = newProgram.ProgramName;
            query.Comment = newProgram.Comment;
            query.ProgramDetails.AddRange(lstNewDT);
            d.SubmitChanges();
        }



        public static void UpdateProgram(int currentId, Program newProgram, List<ProgramDetail> lstNewDT)
        {
            var query = d.Programs.Single(o => o.ProgramID == currentId);
            var query2 = from de in d.ProgramDetails
                         where de.ProgramID == query.ProgramID
                         select de;
            d.ProgramDetails.DeleteAllOnSubmit(query2);
            d.SubmitChanges();
            query.ProgramName = newProgram.ProgramName;
            query.Comment = newProgram.Comment;
            query.ProgramDetails.AddRange(lstNewDT);
            d.SubmitChanges();
        }

        /// <summary>
        /// Xóa khỏi CSDL một chương trình đào tạo
        /// </summary>
        /// <param name="currentProgram"></param>
        public static void DeleteProgram(Program currentProgram)
        {
            //throw new NotImplementedException();
            var query1 = from q in d.ProgramDetails
                         where q.ProgramID == currentProgram.ProgramID
                         select q;
            d.ProgramDetails.DeleteAllOnSubmit(query1);
            d.SubmitChanges();
            var query = from q in d.Programs
                        where q.ProgramID == currentProgram.ProgramID
                        select q;

            d.Programs.DeleteAllOnSubmit(query);
            d.SubmitChanges();
        }
        public static void DeleteProgram(int currentId)
        {
            var query1 = from q in d.ProgramDetails
                         where q.ProgramID == currentId
                         select q;
            d.ProgramDetails.DeleteAllOnSubmit(query1);
            d.SubmitChanges();
            var query = from q in d.Programs
                        where q.ProgramID == currentId
                        select q;

            d.Programs.DeleteAllOnSubmit(query);
            d.SubmitChanges();
        }



        /// <summary>
        /// Lấy danh sách tất cả các nhóm của một thời khóa biểu
        /// </summary>
        /// <param name="scheduleInListId"></param>
        /// <returns></returns>
        public static List<Group> GetAllGroup(int scheduleInListId)
        {
            //throw new NotImplementedException();

            var query = from q in d.Groups
                        where q.ScheduleInListId == scheduleInListId
                        select q;
            string t = "ádsf";
            return query.ToList();
        }

        /// <summary>
        /// Thêm một nhóm vào CSDL
        /// </summary>
        /// <param name="g"></param>
        public static void InsertGroup(Group g)
        {
            //throw new NotImplementedException();
            d.Groups.InsertOnSubmit(g);
            d.SubmitChanges();
        }


        /// <summary>
        /// Update một nhóm
        /// </summary>
        /// <param name="currentGroup"></param>
        /// <param name="g"></param>
        public static void UpdateGroup(Group currentGroup, Group g)
        {
            //throw new NotImplementedException();
            Group gr = d.Groups.Single(o => o.GroupID == currentGroup.GroupID);
            gr.GroupName = g.GroupName;
            gr.Comment = g.Comment;
            gr.ProgramID = g.ProgramID;
            //gr.ScheduleInListId = g.ScheduleInListId;
            gr.SessionID = g.SessionID;
            d.SubmitChanges();
        }
        public static void UpdateGroup(int currentId, Group g)
        {
            Group gr = d.Groups.Single(o => o.GroupID == currentId);
            gr.GroupName = g.GroupName;
            gr.Comment = g.Comment;
            gr.ProgramID = g.ProgramID;
            //gr.ScheduleInListId = g.ScheduleInListId;
            gr.SessionID = g.SessionID;
            d.SubmitChanges();

        }

        /// <summary>
        /// Xóa một nhóm
        /// </summary>
        /// <param name="currentGroup"></param>
        public static void DeleteGroup(Group currentGroup)
        {
            //throw new NotImplementedException();
            var query = from q in d.Groups
                        where q.GroupID == currentGroup.GroupID
                        select q;
            d.Groups.DeleteAllOnSubmit(query);
            d.SubmitChanges();
        }
        public static void DeleteGroup(int id)
        {
            var query = from q in d.Groups
                        where q.GroupID == id
                        select q;
            d.Groups.DeleteAllOnSubmit(query);
            d.SubmitChanges();
        }


        /// <summary>
        /// Lấy danh sách các tiết tự do của một nhóm
        /// </summary>
        /// <param name="currentGroup"></param>
        /// <returns></returns>
        public static List<Subject> GetFreeSubject(Group currentGroup)
        {
            //throw new NotImplementedException();
            List<ProgramDetail> lstDT = (from dt in d.ProgramDetails
                                         where dt.ProgramID == currentGroup.ProgramID
                                         select dt).ToList();
            List<Subject> lstFreeSub = new List<Subject>();
            foreach (ProgramDetail dt in lstDT)
            {
                Subject s = d.Subjects.Single(o => o.SubjectID == dt.SubjectID);
                if (s.NotNeedTeacher > 0)
                {
                    lstFreeSub.Add(s);
                }
            }
            return lstFreeSub;

        }

        /// <summary>
        /// Lấy thông tin giàng buộc môn học phải vào tiết nhất định của một nhóm
        /// </summary>
        /// <param name="subject"></param>
        /// <param name="currentGroup"></param>
        /// <returns></returns>
        public static FixSubjectGroupDayLessionModel GetFixSubjectGroup(Subject subject, Group currentGroup)
        {
            //throw new NotImplementedException();
            var query = from fi in d.FixSubjectSessionLessions
                        where fi.GroupID == currentGroup.GroupID && fi.SubjectID == subject.SubjectID
                        select fi;
            FixSubjectGroupDayLessionModel f = new FixSubjectGroupDayLessionModel();
            f.s = subject;
            if (query.Count() > 0)
            {
                FixSubjectSessionLession fx = query.First();
                Day da = d.Days.Single(o => o.DayID == fx.DayID);
                f.d = da;
                Lession le = d.Lessions.Single(o => o.LessionID == fx.LessionID);
                f.l = le;
                f.isFix = true;
            }
            else
            {
                f.isFix = false;
            }
            return f;

        }



        public static List<FixSubjectSessionLession> GetFixSubjectGroup(int groupId)
        {
            var query = from q in d.FixSubjectSessionLessions
                        where q.GroupID == groupId
                        select q;
            return query.ToList();
        }


        /// <summary>
        /// Lưu giàng buộc fix môn học vào môn tiết nhất định
        /// </summary>
        /// <param name="f"></param>
        public static void SaveFixSubjectGroupDayLession(FixSubjectSessionLession f)
        {
            //throw new NotImplementedException();
            var query = from fi in d.FixSubjectSessionLessions
                        where fi.GroupID == f.GroupID && fi.SubjectID == f.SubjectID
                        select fi;
            if (query.Count() > 0)
            {
                query.First().LessionID = f.LessionID;
                query.First().DayID = f.DayID;
                d.SubmitChanges();
            }
            else
            {
                d.FixSubjectSessionLessions.InsertOnSubmit(f);
                d.SubmitChanges();
            }
        }


        public static void SaveFSL(List<FixSubjectSessionLession> lstFSL)
        {
            foreach (FixSubjectSessionLession fsl in lstFSL)
            {
                SaveFixSubjectGroupDayLession(fsl);
            }
        }



        /// <summary>
        /// Kiểm tra xem tất cả các môn tự do đã được fix
        /// </summary>
        /// <param name="scheduleInListId"></param>
        /// <returns></returns>
        public static bool CheckAllFreeSubjectWasFix(int scheduleInListId)
        {
            //throw new NotImplementedException();
            bool ok = true;
            List<Group> lstGroup = GetAllGroup(scheduleInListId);
            foreach (Group g in lstGroup)
            {
                bool br = false;
                List<Subject> lstSubjects = GetAllSubject(scheduleInListId);
                var programDetails = from de in d.ProgramDetails
                                     where de.ProgramID == g.ProgramID
                                     select de;
                var lstNotNeedTeacher = from su in lstSubjects
                                        join de in programDetails
                                        on su.SubjectID equals de.SubjectID
                                        where su.NotNeedTeacher > 0
                                        select su;
                foreach (Subject s in lstNotNeedTeacher)
                {
                    var query = from o in d.FixSubjectSessionLessions
                                where o.GroupID == g.GroupID && o.SubjectID == s.SubjectID
                                select o;
                    if (query.Count() == 0)
                    {
                        br = true;
                        ok = false;
                        break;
                    }
                }
                if (br)
                {
                    break;
                }
            }
            return ok;

        }

        /// <summary>
        /// Lấy danh sách các giáo viên chưa chủ nhiệm trong một thời khóa biểu
        /// </summary>
        /// <param name="scheduleInListId"></param>
        /// <returns></returns>
        public static List<Teacher> GetAvailTeacher(int scheduleInListId)
        {
            //throw new NotImplementedException();
            List<Teacher> lstAvailTeacher = GetAllTeacher(scheduleInListId);
            List<Class> lstAllClass = GetAllClass(scheduleInListId);
            foreach (Class c in lstAllClass)
            {
                Teacher t = lstAvailTeacher.Single(o => o.TeacherID == c.TeacherID);
                lstAvailTeacher.Remove(t);
            }

            return lstAvailTeacher;

        }

        /// <summary>
        /// Lấy danh sách tất cả các lớp của một thời khóa
        /// </summary>
        /// <param name="scheduleInListId"></param>
        /// <returns></returns>
        public static List<Class> GetAllClass(int scheduleInListId)
        {
            //throw new NotImplementedException();
            var query = from q in d.Classes
                        where q.ScheduleInListId == scheduleInListId
                        select q;
            return query.ToList();
        }

        /// <summary>
        /// Lấy danh sách các giáo viên chủ nhiệm của một thời khóa biểu
        /// </summary>
        /// <param name="scheduleInListId"></param>
        /// <returns></returns>
        public static List<Teacher> GetGVCN(int scheduleInListId)
        {
            //throw new NotImplementedException();
            List<Teacher> lstGVCN = new List<Teacher>();
            List<Class> lstAllClass = GetAllClass(scheduleInListId);
            foreach (Class c in lstAllClass)
            {
                Teacher t = d.Teachers.Single(o => o.TeacherID == c.TeacherID);
                lstGVCN.Add(t);
            }
            return lstGVCN;

        }


        /// <summary>
        /// Lấy các giàng buộc phân công giáo viên dạy môn xác định của một lớp
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public static FixClassTeacherSubjectModel GetFixClassTeacherSubject(Class c)
        {
            //throw new NotImplementedException();
            FixClassTeacherSubjectModel f = new FixClassTeacherSubjectModel();
            f.c = c;
            f.subjects = new List<Subject>();
            f.teachers = new List<Teacher>();
            var lstFix = from fx in d.FixTeacherClassSubjects
                         where fx.ClassID == c.ClassID
                         select fx;
            foreach (FixTeacherClassSubject fx in lstFix)
            {
                Subject s = d.Subjects.Single(o => o.SubjectID == fx.SubjectID);
                Teacher t = d.Teachers.Single(o => o.TeacherID == fx.TeacherID);
                f.subjects.Add(s);
                f.teachers.Add(t);
            }
            return f;

        }

        /// <summary>
        /// Lấy lớp user vừa thêm vào CSDL
        /// </summary>
        /// <param name="scheduleInListId"></param>
        /// <returns></returns>
        public static Class GetLastClass(int scheduleInListId)
        {
            //throw new NotImplementedException();
            List<Class> lstAllClass = GetAllClass(scheduleInListId);
            var c = from c1 in lstAllClass
                    where c1.ClassID == lstAllClass.Max(c2 => c2.ClassID)
                    select c1;
            return c.First();

        }


        /// <summary>
        /// Update thông tin lớp học
        /// </summary>
        /// <param name="currentClass"></param>
        /// <param name="newClass"></param>
        public static void UpdateClass(Class currentClass, Class newClass)
        {
            //throw new NotImplementedException();
            Class c = d.Classes.Single(o => o.ClassID == currentClass.ClassID);
            c.ClassName = newClass.ClassName;
            c.ClassSize = newClass.ClassSize;
            c.Comment = newClass.Comment;
            c.GroupID = newClass.GroupID;
            c.TeacherID = newClass.TeacherID;
            d.SubmitChanges();

        }


        public static void DeleteClass(int classID)
        {
            var query = from q in d.Classes
                        where q.ClassID == classID
                        select q;
            d.Classes.DeleteAllOnSubmit(query);
            d.SubmitChanges();
        }


        /// <summary>
        /// Lay danh sach cac mon hoc cua group.
        /// </summary>
        /// <param name="g"></param>
        /// <returns></returns>
        public static List<Subject> GetSubjectOfGroup(Group g)
        {
            Program p = d.Programs.Single(o => o.ProgramID == g.ProgramID);
            List<ProgramDetail> details = (from de in d.ProgramDetails
                                           where de.ProgramID == p.ProgramID
                                           select de).ToList();
            List<Subject> lstSubject = new List<Subject>();
            foreach (ProgramDetail gd in details)
            {
                Subject s = d.Subjects.First(q => q.SubjectID == gd.SubjectID);
                lstSubject.Add(s);
            }
            return lstSubject;
        }

        public static List<Subject> GetSubjectOfGroup(int gId)
        {
            Group g = d.Groups.First(o => o.GroupID == gId);
            Program p = d.Programs.Single(o => o.ProgramID == g.ProgramID);
            List<ProgramDetail> details = (from de in d.ProgramDetails
                                           where de.ProgramID == p.ProgramID
                                           select de).ToList();
            List<Subject> lstSubject = new List<Subject>();
            foreach (ProgramDetail gd in details)
            {
                Subject s = d.Subjects.First(q => q.SubjectID == gd.SubjectID);
                lstSubject.Add(s);
            }
            return lstSubject;
        }




        /// <summary>
        /// Lấy danh sách các môn học
        /// </summary>
        /// <param name="cl"></param>
        /// <returns></returns>
        public static List<Subject> GetAllSubjectOfClass(Class cl)
        {
            //throw new NotImplementedException();
            Group g = d.Groups.Single(o => o.GroupID == cl.GroupID);
            return GetSubjectOfGroup(g);

        }


        /// <summary>
        /// Lấy ra nhóm mà một lớp trực thuộc
        /// </summary>
        /// <param name="cl"></param>
        /// <returns></returns>
        public static Group GetGroupOfClass(Class cl)
        {
            //throw new NotImplementedException();
            Group g = d.Groups.Single(o => o.GroupID == cl.GroupID);
            return g;
        }



        /// <summary>
        /// Lấy danh sách các giáo viên có thể dạy môn học x
        /// </summary>
        /// <param name="subject"></param>
        /// <returns></returns>
        public static List<Teacher> GetTeacherOfSubject(Subject subject)
        {
            //throw new NotImplementedException();
            var query = from t in d.Teachers
                        join o in d.TeacherDetails
                        on t.TeacherID equals o.TeacherID
                        where o.SubjectID == subject.SubjectID
                        select t;
            return query.ToList();
        }


        /// <summary>
        /// Lưu thông tin phân công giảng dạy của lớp học
        /// </summary>
        /// <param name="lstFixTeacherClassSubject"></param>
        /// <param name="cl"></param>
        public static void SaveFixTeacherClassSubject(List<FixTeacherClassSubject> lstFixTeacherClassSubject, Class cl)
        {
            //throw new NotImplementedException();
            var query = from fi in d.FixTeacherClassSubjects
                        where fi.ClassID == cl.ClassID
                        select fi;
            d.FixTeacherClassSubjects.DeleteAllOnSubmit(query);
            d.SubmitChanges();
            d.FixTeacherClassSubjects.InsertAllOnSubmit(lstFixTeacherClassSubject);
            d.SubmitChanges();

        }


        /// <summary>
        /// Thêm một lớp học
        /// </summary>
        /// <param name="cl"></param>
        public static void InsertClass(Class cl)
        {
            //throw new NotImplementedException();
            d.Classes.InsertOnSubmit(cl);
            d.SubmitChanges();

        }

        public static void UpdateClass(int currentId, Class newClass)
        {
            var query = from q in d.Classes
                        where q.ClassID == currentId
                        select q;
            if (query.Count() > 0)
            {
                Class t = query.ToList()[0];
                t.ClassName = newClass.ClassName;
                t.ClassSize = newClass.ClassSize;
                t.Comment = newClass.Comment;
                t.GroupID = newClass.GroupID;
                t.TeacherID = newClass.TeacherID;
                d.SubmitChanges();
            }
        }



        /// <summary>
        /// Thêm một khách hàng
        /// </summary>
        /// <param name="cus"></param>
        public static void InsertCustomer(Customer cus)
        {
            //throw new NotImplementedException();
            d.Customers.InsertOnSubmit(cus);
            d.SubmitChanges();
        }

        public static Customer GetEnCustomer(int cusID)
        {
            var query = from q in d.Customers
                        where q.CustomerId == cusID
                        select q;
            if (query.Count() == 0)
            {
                return null;
            }
            else
            {
                return query.ToList()[0];
            }

        }

        public static void DeleteCustomer(int cusID)
        {
            Customer cus = d.Customers.Single(o => o.CustomerId == cusID);
            cus.Deleted = 1;
            d.SubmitChanges();

        }

        public static void UpdateCustomer(Customer currentCus, Customer newCus)
        {
            Customer cus = d.Customers.Single(o => o.CustomerId == currentCus.CustomerId);
            cus.BankAccount = newCus.BankAccount;
            cus.BankName = newCus.BankName;
            cus.ContactName = newCus.ContactName;
            cus.ContactPhone = newCus.ContactPhone;
            cus.CustomerAddress = newCus.CustomerAddress;
            cus.CustomerDistrictOrCity = newCus.CustomerDistrictOrCity;
            cus.CustomerName = newCus.CustomerName;
            cus.CustomerPhone = newCus.CustomerPhone;
            cus.CustomerProvinceId = newCus.CustomerProvinceId;
            cus.Deleted = 0;
            cus.Email = newCus.Email;
            cus.LoginName = newCus.LoginName;
            cus.Password = newCus.Password;

            d.SubmitChanges();

        }

        public static List<New> GetAllNews()
        {
            return d.News.ToList();
        }

        public static New getEnNew(int id)
        {
            var query = from q in d.News
                        where q.NewsID == id
                        select q;
            if (query.Count() == 0)
            {
                return null;
            }
            else
            {
                return query.ToList()[0];
            }

        }
        public static void DeleteNews(int newsID)
        {
            var query = from q in d.News
                        where q.NewsID == newsID
                        select q;
            d.News.DeleteAllOnSubmit(query);
            d.SubmitChanges();
        }

        public static List<Province> GetAllProvince()
        {
            //throw new NotImplementedException();
            return d.Provinces.ToList();
        }

        public static List<ListSchedule> GetAllSchedule(int cusId)
        {
            //throw new NotImplementedException();
            var query = from q in d.ListSchedules
                        where q.CustomerId == cusId
                        select q;
            return query.ToList();
        }

        //Check sự tồn tại của thực thể trong CSDL
        public static bool CheckTeacher(int teachId)
        {
            var query = from q in d.Teachers
                        where q.TeacherID == teachId
                        select q;
            if (query.Count() > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public static bool CheckDay(int p)
        {
            //throw new NotImplementedException();
            var query = from q in d.Days
                        where q.DayID == p
                        select q;
            if (query.Count() > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public static bool CheckSession(int p)
        {
            //throw new NotImplementedException();
            var query = from q in d.Sessions
                        where q.SessionID == p
                        select q;
            if (query.Count() > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public static bool CheckSubject(int s)
        {
            var query = from q in d.Subjects
                        where q.SubjectID == s
                        select q;
            if (query.Count() > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public static bool CheckProgram(int id)
        {
            var query = from q in d.Programs
                        where q.ProgramID == id
                        select q;
            if (query.Count() > 0)
            {
                return true;
            }
            else
            {
                return false;
            }

        }
        public static bool CheckGroup(int id)
        {
            var query = from q in d.Groups
                        where q.GroupID == id
                        select q;
            if (query.Count() > 0)
            {
                return true;
            }
            else
            {
                return false;
            }

        }
        public static Program GetProgramById(int id)
        {
            var query = from q in d.Programs
                        where q.ProgramID == id
                        select q;
            if (query.Count() > 0)
            {
                return query.ToList()[0];
            }
            else
            {
                return null;
            }
        }
        public static Teacher GetGVCNOfClass(int classId)
        {
            var query = from q in d.Classes
                        where q.ClassID == classId
                        select q;
            if (query.Count() > 0)
            {
                var q2 = from q in d.Teachers
                         where q.TeacherID == query.ToList()[0].TeacherID
                         select q;
                if (q2.Count() > 0)
                {
                    return q2.ToList()[0];
                }
                else
                {
                    Teacher t = new Teacher()
                    {
                        TeacherID = 0,
                        FullName = "",
                        MinLession = 0,
                        Comment = ""
                    };
                    return t;
                }
            }
            else
            {
                Teacher t = new Teacher()
                {
                    TeacherID = 0,
                    FullName = "",
                    MinLession = 0,
                    Comment = ""
                };
                return t;
            }
        }

        public static bool CheckLession(int p)
        {
            //throw new NotImplementedException();
            var query = from q in d.Lessions
                        where q.LessionID == p
                        select q;
            if (query.Count() > 0)
            {
                return true;
            }
            else
            {
                return false;
            }

        }


        public static void AddNews(New n)
        {
            d.News.InsertOnSubmit(n);
            d.SubmitChanges();
        }

        public static bool CheckClass(int currentId)
        {
            //throw new NotImplementedException();
            var query = from q in d.Classes
                        where q.ClassID == currentId
                        select q;
            if (query.Count() > 0)
            {
                return true;
            }
            else
            {
                return false;
            }

        }
        public static List<Class> GetClassOfGroup(int groupId)
        {
            var query = from q in d.Classes
                        where q.GroupID == groupId
                        select q;
            return query.ToList();
        }
        public static List<Subject> GetSubjectOfTeacher(int teacherId, int classId)
        {
            List<Subject> lstSub = DataBase.GetSubjectOfTeacher(new Teacher() { TeacherID = teacherId });
            Class cl = d.Classes.First(o => o.ClassID == classId);

            List<Subject> lstSubOfClass = DataBase.GetSubjectOfGroup(cl.GroupID);
            var query = from q in lstSub
                        join o in lstSubOfClass
                        on q.SubjectID equals o.SubjectID
                        select q;
            return query.ToList();
        }
        public static List<Subject> GetSubjectOfClass(int classId)
        {
            var query = from q in d.Classes
                        where q.ClassID == classId
                        select q;
            if (query.Count() > 0)
            {
                Class cl = query.ToList()[0];
                List<Subject> lstSub = GetSubjectOfGroup(cl.GroupID);
                return lstSub;
            }
            else
            {
                return new List<Subject>();
            }
        }
        public static Teacher GetTeachFixOfClass(int classId, int subjectId)
        {
            var query = from q in d.FixTeacherClassSubjects
                        where q.ClassID == classId && q.SubjectID == subjectId
                        select q;
            if (query.Count() > 0)
            {
                var query2 = from q in d.Teachers
                             where q.TeacherID == query.ToList()[0].SubjectID
                             select q;
                if (query2.Count() > 0)
                {
                    return query2.ToList()[0];
                }
                else
                {
                    return null;
                }
            }
            else
            {
                return null;
            }
        }
        public static Subject GetFixInfoOfTeacher(int classId, int teacherId)
        {
            var query = from q in d.FixTeacherClassSubjects
                        where q.ClassID == classId && q.TeacherID == teacherId
                        select q;
            if (query.Count() > 0)
            {
                var query2 = from q in d.Subjects
                             where q.SubjectID == query.ToList()[0].SubjectID
                             select q;
                if (query2.Count() > 0)
                {
                    return query2.ToList()[0];
                }
                else
                {
                    return null;
                }
                //return query.ToList()[0];
            }
            else
            {
                return null;
            }
            
        }
        public static void SaveFCSTInfo(List<FixTeacherClassSubject> lstFix)
        {
            if (lstFix.Count > 0)
            {
                int classId = lstFix[0].ClassID;
                //Xoa cac thong tin da fix tu truoc
                var query = from q in d.FixTeacherClassSubjects
                            where q.ClassID == classId
                            select q;
                d.FixTeacherClassSubjects.DeleteAllOnSubmit(query);
                d.SubmitChanges();
                d.FixTeacherClassSubjects.InsertAllOnSubmit(lstFix);
                d.SubmitChanges();
            }
        }

        public static Class GetClassById(int classId)
        {
            //throw new NotImplementedException();
            var query = from q in d.Classes
                        where q.ClassID == classId
                        select q;
            if (query.Count() > 0)
            {
                return query.ToList()[0];
            }
            else
            {
                return null;
            }
        }

        public static FixTeacherClassSubject GetFCST(int schId, int classId, int p)
        {
            //throw new NotImplementedException();
            var query = from q in d.FixTeacherClassSubjects
                        where q.ScheduleInListId == schId && q.ClassID == classId && q.SubjectID == p
                        select q;
            if (query.Count() > 0)
            {
                return query.ToList()[0];
            }
            else
            {
                return null;
            }
        }

        public static List<ProgramDetail> GetProgramOfClass(int p)
        {
            //throw new NotImplementedException();
            var query = from q in d.Classes
                        where q.ClassID == p
                        select q;
            if (query.Count() > 0)
            {
                Class c = query.ToList()[0];
                var query2 = from q in d.Groups
                             where q.GroupID == c.GroupID
                             select q;
                if (query2.Count() > 0)
                {
                    Group g = query2.ToList()[0];
                    var query3 = from q in d.ProgramDetails
                                 where q.ProgramID == g.ProgramID
                                 select q;
                    return query3.ToList();
                }
                else
                {
                    return new List<ProgramDetail>();
                }
            }
            else
            {
                return new List<ProgramDetail>();
            }
        }

        internal static Teacher GetTeacherNone()
        {
            throw new NotImplementedException();
        }
    }
}

